using Microsoft.Xna.Framework;

namespace LunoCode.Render
{
	public class BaseObject
	{
		private Vector3 position;
		private Vector3 scale;
		private Vector3 rotation;
		private Vector3 initialRotation;

		public Vector3 Position
		{
			get { return position; }
			set { position = value; worldStored = false;  }
		}

		public Vector3 Scale
		{
			get { return scale; }
			set { scale = value; worldStored = false;  }
		}

		public Vector3 Rotation
		{
			get { return rotation; }
			set { rotation = value; rotationStored = false; }
		}

		public Vector3 InitialRotation
		{
			get { return initialRotation; }
			set { initialRotation = value; rotationStored = false; }
		}


		private Matrix storedRotationMatrix = Matrix.Identity;
		private Matrix storedWorldMatrix = Matrix.Identity;
		protected bool worldStored = false;
		protected bool rotationStored = false;

		public Matrix World
		{
			get
			{
				if (worldStored == false || rotationStored == false)
				{
					storedWorldMatrix = Matrix.CreateScale(scale)
										* Matrix.CreateRotationX(-MathHelper.PiOver2)
					                    * RotationMatrix
					                    * Matrix.CreateTranslation(position);
					worldStored = true;
				}
				return storedWorldMatrix;
			}
		}

		public Matrix RotationMatrix
		{
			get
			{
				if (rotationStored == false)
				{
					storedRotationMatrix = Matrix.CreateRotationX(initialRotation.X)
					                       * Matrix.CreateRotationZ(initialRotation.Z)
					                       * Matrix.CreateRotationY(initialRotation.Y)
					                       * Matrix.CreateRotationX(rotation.X)
					                       * Matrix.CreateRotationZ(rotation.Z)
					                       * Matrix.CreateRotationY(rotation.Y);
					rotationStored = true;
				}
				return storedRotationMatrix;
			}
		}

		/// <summary>
		/// Move model
		/// </summary>
		public void Move(Vector3 translation)
		{
			position += translation;
			worldStored = false;
		}

		public void Move(float x, float y, float z)
		{
			position.X += x;
			position.Y += y;
			position.Z += z;
			worldStored = false;
		}

		public BaseObject()
		{
			position = Vector3.Zero;
			scale = new Vector3(1, 1, 1);
			rotation = Vector3.Zero;
		}
		protected void Rotate(float dx, float dy, float dz)
		{
			rotation.X += dx;
			rotation.Y += dy;
			rotation.Z += dz;
			rotationStored = false;
		}
		protected void Translate(float dx, float dy, float dz)
		{
			position.X += dx;
			position.Y += dy;
			position.Z += dz;
			worldStored = false;
		}
		public void RecalculateWorldMatrix()
		{
			rotationStored = false;
			worldStored = false;
			Matrix foo = World;
		}
	}
}